<script lang="ts" setup>
  import type { PropType } from 'vue'
  import { computed, ref, unref, watch, watchEffect } from 'vue'
  import { Transfer } from 'ant-design-vue'
  import { get, omit } from 'lodash-es'
  import type { TransferDirection, TransferItem } from 'ant-design-vue/lib/transfer'
  import { isFunction } from '/@/utils/is'
  import { propTypes } from '/@/utils/propTypes'

  defineOptions({ name: 'ApiTransfer' })

  const props = defineProps({
    value: { type: Array as PropType<Array<string>> },
    api: {
      type: Function as PropType<(arg) => Promise<TransferItem[]>>,
      default: null,
    },
    params: { type: Object },
    dataSource: { type: Array as PropType<Array<TransferItem>> },
    immediate: propTypes.bool.def(true),
    alwaysLoad: propTypes.bool.def(false),
    afterFetch: { type: Function },
    resultField: propTypes.string.def(''),
    labelField: propTypes.string.def('title'),
    valueField: propTypes.string.def('key'),
    showSearch: { type: Boolean, default: false },
    disabled: { type: Boolean, default: false },
    filterOption: {
      type: Function as PropType<(inputValue: string, item: TransferItem) => boolean>,
    },
    selectedKeys: { type: Array as PropType<Array<string>> },
    showSelectAll: { type: Boolean, default: true },
    targetKeys: { type: Array as PropType<Array<string>> },
  })
  const emit = defineEmits(['options-change', 'change'])
  // const attrs = useAttrs()

  const _dataSource = ref<TransferItem[]>([])
  const _targetKeys = ref<string[]>([])

  // const getAttrs = computed(() => {
  //   return {
  //     ...(!props.api ? { dataSource: unref(_dataSource) } : {}),
  //     ...attrs,
  //   }
  // })
  const getdataSource = computed(() => {
    const { labelField, valueField } = props

    return unref(_dataSource).reduce((prev, next) => {
      if (next) {
        prev.push({
          ...omit(next, [labelField, valueField]),
          title: next[labelField],
          key: next[valueField],
        })
      }
      return prev
    }, [] as TransferItem[])
  })
  const getTargetKeys = computed<string[]>(() => {
    /* if (unref(_targetKeys).length > 0) {
          return unref(_targetKeys);
        } */
    if (Array.isArray(props.value)) return props.value

    if (Array.isArray(props.targetKeys)) return props.targetKeys

    return []
  })

  function handleChange(keys: string[], direction: TransferDirection, moveKeys: string[]) {
    _targetKeys.value = keys
    console.log(direction)
    console.log(moveKeys)
    emit('change', keys)
  }

  watchEffect(() => {
    props.immediate && !props.alwaysLoad && fetch()
  })

  watch(
    () => props.params,
    () => {
      fetch()
    },
    { deep: true },
  )

  async function fetch() {
    const api = props.api
    if (!api || !isFunction(api)) {
      if (Array.isArray(props.dataSource)) _dataSource.value = props.dataSource

      return
    }
    _dataSource.value = []
    try {
      const res = await api(props.params)
      if (Array.isArray(res)) {
        _dataSource.value = res
        emitChange()
        return
      }
      if (props.resultField) _dataSource.value = get(res, props.resultField) || []

      emitChange()
    } catch (error) {
      console.warn(error)
    }
  }
  function emitChange() {
    emit('options-change', unref(getdataSource))
  }
</script>

<template>
  <Transfer
    :data-source="getdataSource"
    :filter-option="filterOption"
    :render="(item) => item.title"
    :show-select-all="showSelectAll"
    :selected-keys="selectedKeys"
    :target-keys="getTargetKeys"
    :show-search="showSearch"
    :disabled="disabled"
    @change="handleChange"
  />
</template>
